/***************************************************************************
 *   Copyright (C) 2007, 2010 by Lasse Liehu                               *
 *   lliehu@kolumbus.fi                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "notifierworkingstate.h"

#include <QSystemTrayIcon>

NotifierWorkingState::NotifierWorkingState(QSystemTrayIcon& systemTray)
    : mIsUpAndWorking(false), mIsUpAndWorkingOldVal(false),
    mIsOldValInUnsetWorkingState(false),
    mHasOldValBeenInUnsetWorkingState(false), mReasonForNotWorking(None),
    mReasonForNotWorkingDateTimeSet(false), mSystemTray(systemTray)
{
    mReasonForNotWorkingExtraInfo = tr("No problems or errors have occurred, but "
        "haven't even tried to login or to check yet.");
    connect(this, SIGNAL(stateChanged(bool)), this,
        SLOT(informUserOfStateChange(bool) ));
}

NotifierWorkingState::~NotifierWorkingState()
{
}

bool NotifierWorkingState::isUpAndWorking() const
{
    return mIsUpAndWorking;
}

NotifierWorkingState::ReasonForNotWorking NotifierWorkingState::reasonForNotWorking() const
{
    return mReasonForNotWorking;
}

QString NotifierWorkingState::reasonForNotWorkingExtraInfo() const
{
    return mReasonForNotWorkingExtraInfo;
}

bool NotifierWorkingState::isReasonForNotWorkingDateTimeSet() const
{
    return mReasonForNotWorkingDateTimeSet;
}

QDateTime NotifierWorkingState::reasonForNotWorkingDateTime() const
{
    return mReasonForNotWorkingDateTime;
}

/**
 * @attention When the status is set to "up and working" then a call to this
 *     member function actually sets the state. But when you set the state to
 *     "not working" you @b MUST call setReasonForNotWorking() right after
 *     calling this member function.
 */
void NotifierWorkingState::setIsUpAndWorking(bool newVal)
{
    mIsUpAndWorkingOldVal = mIsUpAndWorking;
    if (!mHasOldValBeenInUnsetWorkingState && !mIsOldValInUnsetWorkingState)
    {
        mIsOldValInUnsetWorkingState = true;
    }
    else if (mIsOldValInUnsetWorkingState)
    {
        mIsOldValInUnsetWorkingState = false;
        mHasOldValBeenInUnsetWorkingState = true;
    }
    mIsUpAndWorking = newVal;
    if (mIsUpAndWorking == true)
    {
        mReasonForNotWorking = None;
        mReasonForNotWorkingExtraInfo.clear();
        mReasonForNotWorkingDateTimeSet = false;
        // if old val was "not working"
        // NOTE: if mIsOldValInUnsetWorkingState is true then the result of
        //       the condition is the opposite
        if (!(mIsUpAndWorkingOldVal ^ mIsOldValInUnsetWorkingState) )
        {
            emit stateChanged(mIsUpAndWorking);
        }
        emit stateWasSet(mIsUpAndWorking);
    }
    else
    {
    }
}

/**
 * @attention This should always be called @b after setting of the "is up and
 *     working" state because this method will not save reason and info if that
 *     state is "up and working" and not "not working".
 */
void NotifierWorkingState::setReasonForNotWorking(ReasonForNotWorking reason,
    const QString& extraInfo)
{
    if ((!mIsUpAndWorking) && (mReasonForNotWorking != LoginFailed || reason == LoginFailed))
    {
        if ((!mReasonForNotWorkingDateTimeSet) || mReasonForNotWorking != reason)
        {
            mReasonForNotWorkingDateTime = QDateTime::currentDateTime();
            mReasonForNotWorkingDateTimeSet = true;
        }
        mReasonForNotWorking = reason;
        mReasonForNotWorkingExtraInfo = extraInfo;
    }
    // if old state was "up and working"
    // NOTE: if mIsOldValInUnsetWorkingState is true then the result of
    //       the condition is the opposite
    if (mIsUpAndWorkingOldVal ^ mIsOldValInUnsetWorkingState)
    {
        emit stateChanged(mIsUpAndWorking);
    }
    emit stateWasSet(mIsUpAndWorking);
}

void NotifierWorkingState::informUserOfStateChange(bool newState)
{
    if (!newState)
    {
        mSystemTray.showMessage(tr("Notifier failed and is not working!"),
            tr("Notifier will retry every now and then. Please see the "
               "log for details."));
    }
}
